﻿namespace SuperStarRounds.DockingTasks
{
  using System;
  using System.Drawing;
  using System.Linq;
  using System.Windows.Forms;

  using Classes.FileIO;
  using Classes.Utility;

  using WeifenLuo.WinFormsUI.Docking;

  public class BaseDockingTask : DockContent
  {
    public SuperStar OwnerSuperStar { get; set; }

    /// <summary>
    /// This boolean indicates if the task is being updated preventing changes in multi controls triggering
    /// overlaying updates, only one at a time can be run.
    /// </summary>
    public bool UpdateIsRunning { get; set; }

    // this signature will allow the undocked floating window to be the designer set size and not the weird doc panel one :)
    public void Show(DockPanel dockPanel, DockState dockState, Rectangle floatWindowBounds)
    {
      Show(dockPanel, dockState);

      if (DockHandler.FloatPane == null)
      {
        DockHandler.FloatPane = dockPanel.DockPaneFactory.CreateDockPane(this, DockState.Float, false);
        DockHandler.FloatPane.FloatWindow.StartPosition = FormStartPosition.Manual;
      }

      DockHandler.FloatPane.FloatWindow.Bounds = floatWindowBounds;
    }

    protected void Base_Load()
    {
      // loading mdi children maximised has a known issue that messes with icons - this is the workaround.
      Icon = Icon?.Clone() as Icon;
      Tag = $"{Name} - {DateTime.UtcNow.ToString("O")}"; // used as unique id of instance
    }

    protected void Base_FormClosing()
    {
      if (OwnerSuperStar.IsDisposed) return;

      var removeIndex = -1;
      var indexSearching = -1;
      foreach (var panel in OwnerSuperStar.DockedTasks)
      {
        indexSearching++;
        if (!Tag.Equals(panel.Tag)) continue;
        removeIndex = indexSearching;
      }

      if (removeIndex < 0) return; // not found, so cannot remove
      OwnerSuperStar.DockedTasks.RemoveAt(removeIndex);
    }

    protected void SelectAllText(object sender)
    {
      FormUtility.OnEntrySelectAllText(sender);
    }

    private void InitializeComponent()
    {
      SuspendLayout();
      // 
      // BaseDockingTask
      // 
      AutoScroll = true;
      ClientSize = new Size(356, 261);
      Font = new Font("Microsoft Sans Serif", 8.25F, FontStyle.Regular, GraphicsUnit.Point, 0);
      Name = "BaseDockingTask";
      ResumeLayout(false);

    }

    public void SetLanguage(string language)
    {
      Localize.SetLanguage(language);
      LocalizeAdvisor.SetLanguage(language);
      LocaliseForm();

      // this call effectively "enters" the first focusable field of the form
      // and so sets the get help text to be updated
      SetFocusToFirstControl();
    }


    public void SetFocusToFirstControl()
    {
      foreach (var control in Controls)
      {
        var cast = control as Control;
        if (cast == null) continue;
        if (!cast.CanFocus) continue;
        cast.Focus();
      }
    }

    /// <summary>
    /// Localises the form text of the application using localization strings
    /// held in localisation resource files.
    /// </summary>
    public virtual void LocaliseForm()
    {
      throw new NotImplementedException();
    }

    /// <summary>
    /// Call on each open panel when the content configuration is changed
    /// </summary>
    /// <param name="sender">Holds the object instantiating this event</param>
    /// <param name="e">Holds the event arguments</param>
    public virtual void ResetContent(object sender, EventArgs e)
    {
      throw new NotImplementedException();
    }

    /// <summary>
    /// Used when putting localised text into a control so that it right aligns the end of text
    /// next to the control in such a way that no underlap of text occurs unless it simply will
    /// not fit. An optional maximum left edge setting can be passed to restrict the left side
    /// growth of the text labelling.
    /// In order to move controls at run time, a Point must be passed to the controls Location
    /// attribute, so this function takes a start point, the x and y adjustments and returns the
    /// new Point to be used as the location.
    /// </summary>
    /// <param name="currentPosition">Point providing the current control position</param>
    /// <param name="offsetX">The adjustment in pixels to the X co-ordinate, default is 0</param>
    /// <param name="minX">The minimum that X can be adjusted to, default is 0</param>
    /// <param name="offsetY">The adjustment in pixeld to the Y co-ordinate, default is 0</param>
    /// <param name="minY">The minimum that Y can be adjusted to, default is 0</param>
    /// <returns>Point that represents the adjusted control position.</returns>
    protected static Point LocalPositionAdjust(Point currentPosition, int offsetX = 0, int minX = 0, int offsetY = 0, int minY = 0)
    {
      var newX = (currentPosition.X + offsetX) < minX ? minX : (currentPosition.X + offsetX);
      var newY = (currentPosition.Y + offsetY) < minY ? minY : (currentPosition.Y + offsetY);
      return new Point(newX, newY);
    }

    public ContentConfiguration GetCurrentConfigurationSettings()
    {
      return (from loadedTask in OwnerSuperStar.DockedTasks where loadedTask.Name.Equals("ContentConfiguration")
              select loadedTask as ContentConfiguration).FirstOrDefault();
    }

    /// <summary>
    /// Adds the word provided to the personal dictionary. It also immediately
    /// saves the updated personal dictionary in case of power outages, etc.
    /// </summary>
    /// <param name="word">The word to be added to the personal dictionary</param>
    public void AddToPersonalDictionary(string word)
    {
      OwnerSuperStar.PersonalDictionary.Add(word);
      try
      {
        PersonalDictionarySerializer.SerializePersonalDictionary(OwnerSuperStar.PersonalDictionary, OwnerSuperStar.PersonalDictionaryFile);
      }
      catch (Exception)
      {
        // Any failure means the personal dictionary is not updated
      }
    }
  }
}
